home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / database / bltc121.zip / BORLAND.ZIP / MEMCXB.ASM < prev    next >
Assembly Source File  |  1995-01-05  |  12KB  |  249 lines

  1. TITLE MEMCXB      ;C version
  2. PAGE 55,132
  3. ;multiple routines
  4. ;xb$malloc
  5. ;xb$free
  6. ;xb$SetHandleCount  (no longer available with this replacement module)
  7. ;-----------------------------------------------------------------------|
  8. ;    ScanSoft          (C)1992 Cornel H Huth     ALL RIGHTS RESERVED    |
  9. ;-----------------------------------------------------------------------|
  10. ;     date:      31-Aug-93                                              |
  11. ; function:      Memory routines for C compilers                        |
  12. ;                that do not allow DOS allocations to be mixed with     |
  13. ;                _malloc allocations (including _calloc, etc.)          |
  14. ;    notes:      This malady afflicts Borland C compilers               |
  15. ;                All registers saved since there's no telling what      |
  16. ;                registers the runtime code uses (ax,bp not saved)      |
  17. ;                                                                       |
  18. ;                                                                       |
  19. ;The code below will work in either LARGE or HUGE memory modules.       |
  20. ;It will not, as written, work in the medium model. With minor changes, |
  21. ;the medium model could be supported (though this patch isn't needed    |
  22. ;for Borland medium memory models. Not tested in LARGE.                 |
  23. ;                                                                       |
  24. ;This code was written with MASM 5.10A in mind though TASM should       |
  25. ;handle it, too.                                                        |
  26. ;                                                                       |
  27. ;To assemble:                                                           |
  28. ;                                                                       |
  29. ;       C>masm memcxb /mx;   (/mx=preserve case on globals)             |
  30. ;                                                                       |
  31. ;See FIX104.TXT for more info.                                          |
  32. ;-----------------------------------------------------------------------|
  33. WPTR EQU <WORD PTR>
  34.  
  35.                 .MODEL LARGE,PASCAL
  36.  
  37.         .DATA
  38.         
  39. PUBLIC _maxPackRAM
  40. PUBLIC _maxIndexToken
  41.                 
  42. ;The following max values are for compiler/run-time code that gets flakey
  43. ;on large allocations made using the patch module. These values can be 
  44. ;bumped to there max (65504 and 2, respectively) if your particular RT
  45. ;can handle it. In the default MEMXB.OBJ (this is MEMCXB.OBJ) the max
  46. ;values are used (since no RT is involved to flake out).
  47.             
  48. _maxPackRAM     dw   32768      ;max bytes PackRecords can allocate (8K-63K)
  49. _maxIndexToken  dw   0          ;max bytes Reindex can allocate
  50.                 ;where token 0=32K, 1=64K, and 2+=128K)
  51.                 
  52.                 .CODE
  53.  
  54. EXTRN _malloc:FAR
  55. EXTRN _free:FAR
  56.  
  57.                 ;The Tracker lists are allocated in code segment to minimize
  58.                 ;impact on DGROUP
  59.  
  60.                 ;MAXTRACKER is the number of allocations that can be open at
  61.                 ;any one time. Consider each open file to require one Track.
  62.                 ;A good MAXTRACKER value would be the total number of files you
  63.                 ;require to be open at one time plus 5. Each MAXTRACKER
  64.                 ;requires 6 bytes of code space. Unless you're starving for
  65.                 ;RAM, MAXTRACKER is fine at 254 (uses about 1.5K of code space.)
  66.  
  67. MAXTRACKER EQU 254
  68.  
  69.                 ;TrackerFP stores far pointers as returned by _malloc
  70.                 ;so that _free can be used (_free requires exact FP match)
  71. EVEN
  72. TrackerFP       dd MAXTRACKER DUP (0)   ;32-bit pointer as returned by _malloc
  73.                 dd 0                    ;and required by _free
  74.  
  75.                 ;TrackerSeg stores the 16-bit segment pointer converted from
  76.                 ;the far pointer returned by _malloc. See xb$malloc for how
  77.                 ;this is done. This is used as a lookup value in xb$free.
  78.  
  79. TrackerSeg      dw MAXTRACKER DUP (0)   ;thunk it to a 16-bit segment pointer
  80.                 dw -1
  81.  
  82. ;-----------------------------------------------------------------------|
  83. ;     date:      30-Sep-92                                              |
  84. ; function:      allocate memory                                        |
  85. ;   caller:      FAR, ASSEMBLY                                          |
  86. ;    stack:      n/a                                                    |
  87. ;       in:      bx=paragraphs to allocate                              |
  88. ;      out:      NC=ax=seg                                              |
  89. ;                CY=ax=8=not enough memory                              |
  90. ;     uses:      ax (return)                                            |
  91. ;    notes:      call with bx=FFFF and bx returns w/ largest block free |
  92. ;                (according to DOS)                                     |
  93. ;-----------------------------------------------------------------------|
  94.  
  95. xb$malloc       PROC USES cx dx si di es ds
  96.  
  97.                 cmp     bx,-1           ;just asking for available memory?
  98.                 jne     xb$malloc01     ;no
  99.                 mov ah,48h              ;yes
  100.                 int 21h
  101.                 jmp     SHORT xb$mallocXit
  102.  
  103. xb$malloc01:    mov     cx,MAXTRACKER   ;scan for next free descriptor
  104.                 sub     ax,ax           ;0 indicates available
  105.                 push    cs
  106.                 mov     di,OFFSET TrackerSeg
  107.                 pop     es              ;es:di->TrackSeg start
  108.                 repne scasw
  109.                 jne     xb$mallocEx     ;none available
  110.                 mov     ax,di
  111.                 sub     ax,OFFSET TrackerSeg+2 ;ax=available slot (word)
  112.  
  113.                 push    bx              ;save size for return
  114.                 push    ax              ;save slot
  115.  
  116.         mov    ax,1
  117.         push    ax        ;size of
  118.                 sub     ax,ax
  119.                 push    ax              ;high-word of request
  120.                 mov     ax,bx           ;paras requested
  121.                 inc     ax              ;bump para request so we can norm it
  122.                 shl     ax,1            ;(thunk it would be more like it)
  123.                 shl     ax,1
  124.                 shl     ax,1
  125.                 shl     ax,1            ;paras to bytes
  126.                 push    ax              ;low-word of request
  127.  
  128.                 mov     ax,DGROUP       ;definite requirement for C7
  129.                 mov     ds,ax           ;(though this patch not needed for C7!)
  130.         
  131.                 call    _malloc         ;appease the Borland Gods
  132.         add    sp,6        ;here dx:ax is far pointer to block
  133.  
  134.                 pop     di              ;get back slot
  135.  
  136.                 mov     bx,dx           ;check for null pointer return
  137.                 or      bx,ax           ;allocation okay?
  138.                 pop     bx              ;get back size
  139.                 jz      xb$mallocEx     ;no
  140.  
  141.                 mov     si,di           ;word slot index for TrackerSeg
  142.                 shl     di,1            ;dword slot index for TrackerFP
  143.                 mov     WPTR cs:[TrackerFP+di],ax
  144.                 mov     WPTR cs:[TrackerFP+di+2],dx
  145.  
  146.                 ;normalize the 32-bit pointer to a 16-bit segment pointer
  147.                 ;we can do this because we requested 1 additional paragraph
  148.                 ;so that we can just drop the normalized offset and start
  149.                 ;using the allocated memory block at the next paragraph
  150.  
  151.                 ;;since we won't be using the fractional-para offset of the
  152.                 ;;norm'ed far pointer we can skip the overhead
  153.  
  154.                 ;;mov     bx,ax           ;save full offset
  155.                 ;;and     ax,000Fh        ;non-paragraph portion
  156.                 ;;mov     cx,ax           ;ax is normalized offset
  157.                 ;;mov     ax,bx           ;get full offset back
  158.  
  159.                 shr     ax,1            ;convert offset to full paras
  160.                 shr     ax,1
  161.                 shr     ax,1
  162.                 shr     ax,1
  163.                 add     ax,dx           ;add segment in
  164.                 inc     ax              ;bump to next paragraph
  165.                 mov     cs:[TrackerSeg+si],ax
  166.                 clc                     ;return 16-bit segment pointer in ax
  167. xb$mallocXit:   ret                     ;that BULLET will use
  168.  
  169. xb$mallocEx:    mov     ax,8
  170.                 stc
  171.                 jmp     SHORT xb$mallocXit
  172.  
  173. xb$malloc       ENDP
  174.  
  175. ;-----------------------------------------------------------------------|
  176. ;     date:      30-Sep-92                                              |
  177. ; function:      free allocated memory                                  |
  178. ;   caller:      FAR, ASSEMBLY                                          |
  179. ;    stack:      n/a                                                    |
  180. ;       in:      es=segment pointer of block to free                    |
  181. ;      out:      NC=okay (at least this code, _free has not return code)|
  182. ;                CY=ax=9 invalid block (segment not in descriptor list  |
  183. ;     uses:      ax (return)                                            |
  184. ;    notes:      see xb$malloc above for more info                      |
  185. ;-----------------------------------------------------------------------|
  186.  
  187. xb$free         PROC USES bx cx dx si di ds es
  188.  
  189.                 mov     cx,MAXTRACKER   ;scan for matching descriptor
  190.                 mov     ax,es           ;search for this segment pointer
  191.                 push    cs
  192.                 mov     di,OFFSET TrackerSeg
  193.                 pop     es              ;es:di->TrackerSeg start
  194.                 repne scasw
  195.                 jne     xb$freeEx       ;not found, must be invalid block
  196.  
  197.                 sub     ax,ax
  198.                 sub     di,OFFSET TrackerSeg+2  ;di=matched slot (word)
  199.  
  200.                 push    di                      ;save slot
  201.  
  202.                 shl     di,1                    ;dword slot index
  203.                 push    WPTR cs:[TrackerFP+di+2];segment to block to release
  204.                 push    WPTR cs:[TrackerFP+di]  ;offset
  205.  
  206.                 mov     ax,DGROUP
  207.                 mov     ds,ax
  208.  
  209.                 call    _free                   ;appease them some more
  210.                 add     sp,4
  211.                 sub     ax,ax
  212.                 mov     WPTR cs:[TrackerFP+di+2],ax     ;clear descriptor info
  213.                 mov     WPTR cs:[TrackerFP+di],ax
  214.  
  215.                 pop     di                              ;get word slot index
  216.  
  217.                 mov     cs:[TrackerSeg+di],ax           ;make slot available
  218. xb$freeXit:     ret
  219.  
  220. xb$freeEx:      mov     ax,9
  221.                 stc
  222.                 jmp     xb$freeXit
  223. xb$free         ENDP
  224.  
  225. ;-----------------------------------------------------------------------|
  226. ;     date:      30-Sep-92                                              |
  227. ; function:      set maximum handle count                               |
  228. ;   caller:      FAR, ASSEMBLY                                          |
  229. ;    stack:      n/a                                                    |
  230. ;       in:      bx=handle count                                        |
  231. ;      out:      NC=okay                                                |
  232. ;                CY=ax=error number                                     |
  233. ;     uses:      ax (return)                                            |
  234. ;    notes:      Cannot use DOS INT21/67 since it makes a DOS memory    |
  235. ;                allocation call which, as you know, cannot be          |
  236. ;                issued when using Borland's _malloc functions.         |
  237. ;-----------------------------------------------------------------------|
  238.  
  239. xb$SetHandleCount PROC
  240.  
  241.                 mov     ax,1            ;function not available for Borland C
  242.                 stc                     ;via this route
  243.                 ret
  244.  
  245. xb$SetHandleCount ENDP
  246.  
  247.                 END
  248.  
  249.